package com.pingan.glue.gluegame.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.pingan.glue.gluegame.common.AwardContent;
import com.pingan.glue.gluegame.controller.form.FilmResponse;
import com.pingan.glue.gluegame.dao.AwardContentDao;
import com.pingan.glue.gluegame.dao.FaceFieldDao;
import com.pingan.glue.gluegame.dao.FriendUserDao;
import com.pingan.glue.gluegame.dao.GameOrderDao;
import com.pingan.glue.gluegame.entity.AwardContentEntity;
import com.pingan.glue.gluegame.entity.FaceFieldEntity;
import com.pingan.glue.gluegame.entity.FriendUserEntity;
import com.pingan.glue.gluegame.entity.GameOrderEntity;
import com.pingan.glue.gluegame.http.GlueGameClient;
import com.pingan.glue.gluegame.service.GameOrderService;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class GameOrderServiceImpl implements GameOrderService {
    private final static Logger LOGGER = LoggerFactory.getLogger(GameOrderServiceImpl.class);

    private static final String filmUrl = "https://movie.douban.com";

    @Resource
    private GameOrderDao gameOrderDao;

    @Resource
    private FaceFieldDao faceFieldDao;

    @Resource
    private AwardContentDao awardContentDao;

    @Resource
    private GlueGameClient glueGameClient;

    @Override
    public Long saveOrUpdateGameOrder(FriendUserEntity entity, Long finishTime) {
        LOGGER.info("GameOrderServiceImpl_saveOrUpdateGameOrder_param:{},finishTime:{} ", JSONObject.toJSONString(entity),finishTime);
        GameOrderEntity where = new GameOrderEntity();
        where.setUserId(entity.getUserId());
        GameOrderEntity gameOrder = gameOrderDao.selectOne(where);
        Long result;
        if (finishTime == null){
            result = gameOrder == null?Long.MAX_VALUE:gameOrder.getGameTime();
        }else {
            if (gameOrder == null) {
                gameOrder = new GameOrderEntity();
                gameOrder.setMobile(entity.getMobile());
                gameOrder.setUserId(entity.getUserId());
                gameOrder.setGameTime(finishTime);
                gameOrder.setUsername(entity.getUsername());
                gameOrderDao.insert(gameOrder);
                result =Long.MAX_VALUE;
            } else if (finishTime < gameOrder.getGameTime()) {
                result = gameOrder.getGameTime();
                gameOrder.setGameTime(finishTime);
                gameOrder.setUpdateTime(new Date());
                gameOrderDao.updateById(gameOrder);
            } else {
                result = gameOrder.getGameTime();
                LOGGER.info("GameOrderServiceImpl_saveOrUpdateGameOrder:本次没有之前成绩好，不更新排名");

            }
        }
        LOGGER.info("GameOrderServiceImpl_saveOrUpdateGameOrder_result:{}", result);
        return result;
    }

    @Override
    public List<GameOrderEntity> queryGameOrder(int current,int size) {
        LOGGER.info("GameOrderServiceImpl_queryGameOrder_current:{},size:{}",current,size);
        Page<GameOrderEntity> page = new Page<>(current,size);
        EntityWrapper<GameOrderEntity> entityWrapper =new EntityWrapper<>();
        entityWrapper.orderAsc(Lists.newArrayList("game_time"));
        List<GameOrderEntity> list =  gameOrderDao.selectPage(page,entityWrapper);
        list.forEach(order->{
            FaceFieldEntity entity = faceFieldDao.queryByuserId(order.getUserId());
            markMobile(order,entity);
            order.setFacePath(entity.getFacePath());
        });
        return list;
    }

    private void markMobile(GameOrderEntity order, FaceFieldEntity entity) {
        String mobileFull = entity.getMobile();
        if(StringUtils.isBlank(mobileFull)){
            order.setMobile("");
        }
        if (mobileFull.length() ==11){
            StringBuilder sb =new StringBuilder();
            sb.append(mobileFull.substring(0,3)).append("****").append(mobileFull.substring(7,11));
            order.setMobile(sb.toString());
        }

    }

    @Override
    public String calculateAward(FriendUserEntity entity,Long finishTime) {
        LOGGER.info("GameOrderServiceImpl_calculateAward_entity:{},finishTime:{}",JSONObject.toJSONString(entity),finishTime);
        if(finishTime == null){
            return "";
        }
        AwardContentEntity awardContent = new AwardContentEntity();
        awardContent.setMobile(entity.getMobile());
        awardContent.setUserId(entity.getUserId());
        awardContent.setUsername(entity.getUsername());
        awardContent.setFinishTime(finishTime);
        String award;
        int order = getOrder(finishTime);
        if (order ==-1){
            award = AwardContent.NO_TICKET.name();
        }else {
            award = AwardContent.content(order+1);
        }
        awardContent.setAward(award);
        awardContentDao.insert(awardContent);
        return award;
    }

    public List<FilmResponse> film(){
        LOGGER.info("GameOrderServiceImpl_film start");
        List<FilmResponse> filmResponses = new ArrayList<>();
        String s = glueGameClient.getString(filmUrl);
        Document doc=Jsoup.parse(s, filmUrl);
        Elements allLi = doc.select("#screening>div.screening-bd>ul>li");
        for(int i=0;i<8;i++){
            FilmResponse filmResponse = new FilmResponse();
            String url = allLi.get(i).select("li").get(2).select("a").attr("href");
            String filmString = glueGameClient.getString(url);
            Document filmDoc=Jsoup.parse(filmString, url);
            String stringJSON = filmDoc.select("head>script").get(7).html();
            stringJSON = stringJSON.replaceAll("@","&");
            JSONObject json = JSON.parseObject(stringJSON);
            findFileName(filmResponse, json);
            findDirector(filmResponse, json);
            findActor(filmResponse, json);
            language(filmResponse, filmDoc);
            filmResponses.add(filmResponse);
        }
        return filmResponses;
    }

    @Override
    public List<AwardContentEntity> record(String mobile) {
        LOGGER.info("GameOrderServiceImpl_record_mobile:{}",mobile);
        EntityWrapper<AwardContentEntity> entityWrapper =new EntityWrapper<>();
        entityWrapper.eq("mobile",mobile);
        return awardContentDao.selectList(entityWrapper);
        //return null;
    }

    private void findFileName(FilmResponse filmResponse, JSONObject json) {
        filmResponse.setFileImage(json.getString("image"));
        filmResponse.setFileName(json.getString("name"));
        filmResponse.setScore(json.getJSONObject("aggregateRating").getString("ratingValue"));
    }

    private void findDirector(FilmResponse filmResponse, JSONObject json) {
        try {
            JSONArray genre = json.getJSONArray("genre");
            filmResponse.setFilmType(StringUtils.join(genre, "/"));
            JSONArray director = json.getJSONArray("director");
            StringBuilder sb = new StringBuilder();
            director.forEach(d -> {
                sb.append(((JSONObject) d).getString("name").split(" ")[0]).append("/");
            });
            String directorStr = sb.toString();
            directorStr = directorStr.length() != 0 ? directorStr.substring(0, directorStr.length() - 1) : "";
            filmResponse.setDirector(directorStr);
        }catch (Exception e){
            LOGGER.info("findDirector:error",e);
        }
    }

    private void findActor(FilmResponse filmResponse, JSONObject json) {
        try {
            JSONArray actor = json.getJSONArray("actor");
            StringBuilder actorS = new StringBuilder();
            for (int j = 0; j < 3; j++) {
                JSONObject o = (JSONObject) actor.get(j);
                String name = o.getString("name").split(" ")[0];
                actorS.append(name).append("/");
            }
            String actorStr = actorS.toString();
            actorStr = actorStr.length() != 0 ? actorStr.substring(0, actorStr.length() - 1) : "";
            filmResponse.setLeadArtist(actorStr);
        }catch (Exception e){
            LOGGER.info("findActor:error",e);
        }
    }

    private void language(FilmResponse filmResponse, Document filmDoc) {
        try {
            String info = filmDoc.select("#info").html();
            int index = info.indexOf("<span class=\"pl\">语言:</span>");
            int indexEnd = info.indexOf("<span class=\"pl\">上映日期:</span>");
            filmResponse.setLanguage(info.substring(index + "<span class=\"pl\">语言:</span>".length() + 1, indexEnd - 9));
        }catch (Exception e){
            LOGGER.info("language:error",e);
        }
    }

    private void filmMainInfo(FilmResponse filmResponse, Elements e){
        String url = e.get(0).attr("href");
        String s = glueGameClient.getString(filmUrl+url);
        LOGGER.info("filmMainInfo_result:{}",s);

    }

    @Override
    public int getOrder(Long finishTime){
        return gameOrderDao.selectGameRankingLtTime(finishTime);
    }

}
